package math;

import javax.vecmath.*;

public class Spherical {
	public static final double MAX_Z_ANGLE = Math.PI/2;
	public static final double MIN_Z_ANGLE = -Math.PI/2;

	private double zAngle; // latitude
	private double yAngle; // longitude
	
	public Spherical(double zAngle, double yAngle) {
		this.set(zAngle, yAngle);
	}
	
	public Spherical() {
		this(0, 0);
	}
	
	public Spherical(Spherical spherical) {
		this.set(spherical);
	}

	public double getZ() {
		return zAngle;
	}
	
	public double getY() {
		return yAngle;
	}
	
	public void set(double zAngle, double yAngle) {
		this.setZ(zAngle);
		this.yAngle = yAngle;
	}
	
	public void setZ(double zAngle) {
		this.zAngle = zAngle;
		if (this.zAngle > MAX_Z_ANGLE)
			this.zAngle = MAX_Z_ANGLE;
		else if (this.zAngle < MIN_Z_ANGLE)
			this.zAngle = MIN_Z_ANGLE;
	}

	public void setY(double yAngle) {
		this.yAngle = yAngle;
	}
	
	public Vector3d getVector() {
		Vector3d v = new Vector3d();
		double cosZ = Math.cos(zAngle);
		v.x = cosZ * Math.cos(-yAngle);
		v.y = Math.sin(zAngle);
		v.z = cosZ * Math.sin(-yAngle);

		return v;
	}
	
	public void setVector(Tuple3d t) {
		Vector3d v = new Vector3d(t);
		v.normalize();
		
		zAngle = Math.asin(v.y);
		yAngle = Math.atan2(-v.z, v.x);
	}
	
	public void invert() {
		zAngle = -zAngle;
		yAngle = yAngle + Math.PI;
		if (yAngle > Math.PI) {
			yAngle -= Math.PI*2;
		}
	}
	
	@Override
	public String toString() {
		return "[Spherical: zAngle="+zAngle+" yAngle="+yAngle+"]";
	}

	public void set(Spherical orientation) {
		yAngle = orientation.getY();
		zAngle = orientation.getZ();
	}
	
	public boolean isParallell(Spherical other) {
		Vector3d myVector = this.getVector();
		Vector3d otherVector = other.getVector();
		double angle = myVector.angle(otherVector);
		return Precision.compare(0, angle) || Precision.compare(Math.PI, angle);
	}
}
